Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

selinux-policy: adjust kernel permissions for NFS #205

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from

Conversation

bcressey
Copy link
Contributor

Issue number:
Fixes bottlerocket-os/bottlerocket#4116

Description of changes:
When serving files over NFS, the kernel's permissions to access the inode are checked when determining whether the file can be executed by clients. If the kernel lacks permission, then the client will see a permission error and won't be able to execute the program.

Work around this by allowing the kernel access to execute mutable files, while denying it permission to execute a new program without transitioning to a new SELinux context.

To close off other potential paths to execution, define a transition to a "forbidden" type that is explicitly denied, and deny the use of any object as an entry point to that domain.

Testing done:
Verified that the test case in the related issue now passes.

Added a test case to attempt to trigger kernel execution of untrusted code via one of the well-known forms of container escape - installing a new core pattern handler. Confirmed that execution was blocked:

[ 1535.724944] audit: type=1400 audit(1729528842.857:147): avc:  denied  { execute_no_trans } for  pid=26787 comm="kworker/u8:4" path="/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/172/fs/tmp/core-pattern-escape.sh" dev="nvme1n1p1" ino=54842222 scontext=system_u:system_r:kernel_t:s0 tcontext=system_u:object_r:data_t:s0:c346,c677 tclass=file permissive=0

Terms of contribution:

By submitting this pull request, I agree that this contribution is dual-licensed under the terms of both the Apache License, version 2.0, and the MIT license.

When serving files over NFS, the kernel's permissions to access the
inode are checked when determining whether the file can be executed
by clients. If the kernel lacks permission, then the client will see
a permission error and won't be able to execute the program.

Work around this by allowing the kernel access to execute mutable
files, while denying it permission to execute a new program without
transitioning to a new SELinux context.

To close off other potential paths to execution, define a transition
to a "forbidden" type that is explicitly denied, and deny the use of
any object as an entry point to that domain.

Signed-off-by: Ben Cressey <[email protected]>
Comment on lines +92 to +93
(or (and (eq t1 trusted_s)
(neq t2 forbidden_t))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this so that any rules related to process transitions wouldn't be affected by the presence of MLS categories on the label. Previously it was a blanket "allow this for trusted subjects" and now it is "allow this for trusted subjects, unless the target context is forbidden".

@@ -166,10 +166,28 @@
; Subjects that must run verified code can execute immutable objects, since
; those are all protected by dm-verity.
(allow verified_s immutable_o (files (execute)))
(allow kernel_t immutable_o (files (execute)))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is necessary because kernel_t dropped out of the verified_s set.

; Ideally the kernel would also be denied permission to execute mutable
; objects. However, this breaks certain scenarios such as serving files
; over NFS, where the kernel's permissions are checked.
(allow kernel_t mutable_o (file (execute)))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the actual fix to the NFS serving issue.

Note that files (execute) grants both "execute" and "execute_no_trans"; I've moved to the more specific file here in order to split up those two permissions.


; Prevent the kernel from executing mutable objects by blocking execution
; unless there's a defined transition.
(neverallow kernel_t mutable_o (file (execute_no_trans)))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This prevents execution because of this check in the "no transition" branch.

; Backstop against kernel execution of mutable objects by defining a type
; transition, which is then explicitly disallowed.
(typetransition kernel_t mutable_o process forbidden_t)
(neverallow kernel_t forbidden_t (processes (transform)))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This prevents execution because of this check in the "transition" branch.

(neverallow kernel_t forbidden_t (processes (transform)))

; Block the use of any object as an entry point to the forbidden type.
(neverallow forbidden_t all_o (files (enter)))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This causes the next check in the "transition" branch to fail.

Comment on lines +71 to +74
; Processes that should never exist.
(type forbidden_t)
(roletype system_r forbidden_t)
(context forbidden (system_u system_r forbidden_t s0))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is boilerplate to define the forbidden_t type.

Comment on lines +81 to +82
container_t control_t super_t
forbidden_t))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add forbidden_t to the set of all subjects (all_s) since there are a couple "neverallow" rules that should apply to it also.

Comment on lines +130 to +131
(typeattributeset verified_s (xor (host_s) (
runtime_t mount_t api_t init_t kernel_t)))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This drops kernel_t from the verified_s set, so that we can retain the more restrictive rule:

(neverallow verified_s mutable_o (files (execute)))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Cannot execute binaries stored in an NFS Server running on a Bottlerocket node
1 participant